<?php
require_once(__DIR__."/../db/Db.class.php");
class ModelCodeGenerator{
    var $defData;
    var $namespace;
    var $name;
    var $root_dir;
    function __construct($rootDir,$jsonDef,$name,$ns=null)
    {
        $this->defData= $jsonDef;
        $this->namespace = $ns;
        $this->name = $name;
        $this->root_dir = $rootDir;
    }

    function genGenerated(){
        $code = "<?php\n";$def = $this->defData;
        $fullname ="";
        if($this->namespace){
            $fullname.=str_replace("/",'\\',$this->namespace);
            $code .= "namespace ".$fullname.";\n";
        }
        $code.="require_once('$this->root_dir/libs/Validator.class.php');\n";
        $code.="require_once('$this->root_dir/libs/db.inc.php');\n";
        $des = isset($this->defData["description"])?$this->defData["description"]:null;
        if($des) $code.="/**************************
$des
*******************************/\n";
        $code .= "class ".$this->name;
        if($fullname)$fullname.="\\$this->name";else $fullname = $this->name;
        $extends = isset($def["extends"])?$def["extends"]:null;
        if($extends) $code .= " extends ".str_replace("/",'\\',$extends);
        else $code .= " extends \\db\\DbSet";
        $code .=" {\n";
        $props = &$def["props"];
        $fieldnames = "";
        $var_list = "";
        $validates_func = "";
        
        $primary=null;
        foreach( $props as $pname=>$prop_def ){
            $des= isset($prop_def["description"])?$prop_def["description"]:"";
            if(trim($des)) $var_list.="\t/*".$des."*/\n";
            if(isset($prop_def["primary"])) $primary = $pname;
            if($fieldnames) $fieldnames.=",";
            $fieldnames.="'$pname'";
            $var_list.= $this->genPropertyValidateCode($pname,$prop_def);
            
            
            $validates_func.="
        if(!\$allows || in_array('$pname',\$allows)){
            \$rs = \$this->validate_$pname();
            if(\$rs!==true) \$results['$pname']=\$rs;
        }";
        }
        $code.=$var_list;
        $code.="
    public function validate(\$allows=null){
$validates_func
    }
";
        
        $code.="\tstatic \$DB_FIELDNAMES=[$fieldnames];\n";
        $code.="\tstatic \$DB_PRIMARY='$primary';\n";
        $code.="}\n";
        return $code;
    }

    protected function genPropertyValidateCode($pname,&$prop_def){
        $code = "
    public function validate_".$pname."(){
        if(!\$this->_current_) return true;
        \$value = isset(\$this->_current_['$pname'])?\$this->_current_['$pname']:null;
    ";
        $type = isset($prop_def["type"])?$prop_def["type"]:null;
        $len = isset($prop_def["length"])?$prop_def["length"]:null;
        $rules = isset($prop_def["rules"])?$prop_def["rules"]:null;
        $required = $rules?(isset($rules["required"])?$rules["required"]:null):false;
        
        if($required){
            if($required==="strongly"){
                $code.="\t\tif(!trim(\$value)) return array('type'=>'required','args'=>$required);\n";
            }else {
                $code.="\t\tif(!\$value) return array('type'=>'required','args'=>$required);\n";
            }
        }
        if($type!=="int" && $type!=="float" && $type!=="double" && $type!=="boolean" && $type!=="decimal"){
            if($len) $code .="\t\tif(strlen(\$value)>$len) return array('type'=>'max','args'=>$len);\n";
        }
        if($rules) foreach($rules as $ruleName=>$ruleArgs){
            $code .="\t\t\$rs = method_exists('\Validator','$ruleName')?\Validator::$ruleName(\$value,'$ruleArgs'):true;\n\t\tif(\$rs) return array('type'=>'$ruleName','args'=>'$ruleArgs');\n";
        }
        $code.= "\t\treturn true;\n\t}\n";
        return $code;
    }

}